from __future__ import print_function
import argparse
import os
import pkg_resources
import sys
import logging

from deploy.decorators import catches
from deploy import log
from deploy import devices
from deploy import configuration
from deploy import conf
from deploy import exceptions
from deploy import terminal
from deploy import superx


class Volume(object):
    _help = """
superx-deploy: Deploy SuperX Environment.

Log Path: {log_path}
Common Conf: {ceph_path}

{sub_help}
{warning}
    """

    def __init__(self, argv=None, parse=True):
        self.mapper = {
            'deploy': superx.Deploy,
            'lvm': devices.lvm.LVM,
            'simple': devices.simple.Simple,
        }
        if argv is None:
            self.argv = sys.argv
        else:
            self.argv = argv
        if parse:
            self.main(self.argv)

    def help(self, warning=False):
        warning = 'See "superx-deploy --help" for full list of options.' if warning else ''
        return self._help.format(
            warning=warning,
            log_path=conf.log_path,
            ceph_path=self.stat_ceph_conf(),
            sub_help=terminal.subhelp(self.mapper),
        )

    def load_log_path(self):
        conf.log_path = '/var/log/'

    def stat_ceph_conf(self):
        try:
            configuration.load(conf.path)
            return terminal.green(conf.path)
        except exceptions.ConfigurationError as error:
            return terminal.red(error)

    def _get_split_args(self):
        subcommands = self.mapper.keys()
        slice_on_index = len(self.argv) + 1
        pruned_args = self.argv[1:]
        for count, arg in enumerate(pruned_args):
            if arg in subcommands:
                slice_on_index = count
                break
        return pruned_args[:slice_on_index], pruned_args[slice_on_index:]

    @catches()
    def main(self, argv):
        # these need to be available for the help, which gets parsed super
        # early
        configuration.load_ceph_conf_path()
        self.load_log_path()
        main_args, subcommand_args = self._get_split_args()
        # no flags where passed in, return the help menu instead of waiting for
        # argparse which will end up complaning that there are no args
        if len(argv) <= 1:
            print(self.help(warning=True))
            raise SystemExit(0)
        parser = argparse.ArgumentParser(
            prog='superx-deploy',
            formatter_class=argparse.RawDescriptionHelpFormatter,
            description=self.help(),
        )
        parser.add_argument(
            '--log-level',
            default='debug',
            help='Change the file log level (defaults to debug)',
        )
        parser.add_argument(
            '--log-path',
            default='/var/log/',
            help='Change the deploy log path (defaults to /var/log/deploy.log)',
        )
        parser.add_argument(
            '--conf-file',
            default='/etc/SuperX/deploy.conf',
            help='Give the deploy arguments(defaults to /etc/SuperX/deploy.conf)',
        )
        args = parser.parse_args(main_args)
        conf.log_path = args.log_path
        if os.path.isdir(conf.log_path):
            conf.log_path = os.path.join(args.log_path, 'deploy.log')
        log.setup()
        log.setup_console()
        logger = logging.getLogger(__name__)
        logger.info("Running command: superx-deploy %s %s", " ".join(main_args), " ".join(subcommand_args))
        # set all variables from args and load everything needed according to
        # them
        configuration.load_ceph_conf_path(cluster_name='ceph')
        try:
            conf.ceph = configuration.load(conf.path)
        except exceptions.ConfigurationError as error:
            # we warn only here, because it is possible that the configuration
            # file is not needed, or that it will be loaded by some other means
            # (like reading from lvm tags)
            logger.exception('ignoring inability to load ceph.conf')
            terminal.red(error)
        # dispatch to sub-commands
        terminal.dispatch(self.mapper, subcommand_args)
